#!/bin/bash
# vim: fdm=marker fmr=[[[,]]] cms=\ #%s#

build_common()
{ #[[[#
    local pkg=$RELEASE_DIR/common.tar
    if [[ $CLEAN == N ]]
    then
        if [[ -f "${pkg}.gz" ]]
        then
            echo "common already built"
            return 0
        fi
    fi
    rm -f ${pkg} ${pkg}.gz

    cd common/c         # /common/c
    make clean
    make release
    if (( $? != 0 ))
    then
        echo "Error: compile lib release fail"
        return 1
    fi
    make
    if (( $? != 0 ))
    then
        echo "Error: compile lib debug fail"
        return 1
    fi
    cd ../..            # /
    tar --exclude ".svn" -rf $pkg \
        common/c/include \
        common/c/lib/{libsoar_g.a,libsoar.a} \
        common/c/sample

    tar --exclude ".svn" --exclude "*.pyc" -rf $pkg common/python

    tar --exclude ".svn" -rf $pkg common/bash

    tar --exclude ".svn" -rf $pkg common/bin

    gzip $pkg

    echo "Build common succeed"
} #]]]#

build_web()
{ #[[[#
    local pkg=$RELEASE_DIR/web.tar
    if [[ $CLEAN == Y || ! -e ${pkg}.gz ]]
    then
        rm -f ${pkg} ${pkg}.gz
        cd web
        ./build.sh
        if (( $? != 0 ))
        then
            echo "Error: compile web fail"
            return 1
        fi
        cd ..
        tar -rf $pkg -C /opt/soar/web \
        apache/bin apache/conf apache/lib apache/modules apache/php
        tar -rf $pkg -C /opt/soar/web \
        nginx/conf nginx/bin/svrctl nginx/php nginx/sbin
        tar -rf $pkg -C /opt/soar/web \
        htdocs/test phpinc/soar
        gzip $pkg
        echo "Build web succeed"
    else
        echo "web already built"
    fi
} #]]]#

build_svcnode()
{ #[[[#
    local pkg=$RELEASE_DIR/svcnode.tar
    if [[ $CLEAN == N ]]
    then
        if [[ -f "${pkg}.gz" ]]
        then
            echo "svcnode already built"
            return 0
        fi
    fi
    rm -f ${pkg} ${pkg}.gz

    cd svcnode          # /svcnode

    tar --exclude ".svn" -rf $pkg tool

    local sn
    for sn in sn_log sn_passwd sn_session sn_secure sn_mailfwd sn_confirm
    do
        cd $sn
        make clean
        make release
        if (( $? != 0 ))
        then
            echo "Error: compile $sn fail"
            return 1
        fi
        cd ..
        tar --exclude ".svn" -rf $pkg $sn/{svrctl,server.cnfg,$sn,tool}

        case $sn in
        sn_passwd)
            tar --exclude ".svn" -rf $pkg $sn/db/initdb
            ;;
        sn_secure)
            tar --exclude ".svn" -rf $pkg $sn/key
            ;;
        sn_mailfwd)
            tar --exclude ".svn" -rf $pkg $sn/black.lst
            ;;
        sn_confirm)
            tar --exclude ".svn" -rf $pkg $sn/font/DejaVuSansMono.ttf
            ;;
        esac
    done

    cd ..               # /

    gzip $pkg

    echo "Build svcnode succeed"
} #]]]#

_lite()
{ #[[[#
    cd lite/sys         # /svcenv/lite/sys
    cd agent            # /svcenv/lite/sys/agent
    make clean
    make release
    if (( $? != 0 ))
    then
        echo "Error: compile svcenv.lite.sys.agent fail"
        return 1
    fi
    cd ..               # /svcenv/lite/sys
    cd skeleton         # /svcenv/lite/sys/skeleton
    make clean
    make
    if (( $? != 0 ))
    then
        echo "Error: compile svcenv.lite.sys.skeleton fail"
        return 1
    fi
    cd ..               # /svcenv/lite/sys
    cd ../..            # /svcenv/
    tar --exclude ".svn" -rf $pkg \
    lite/etc/svcenv.sh lite/etc/svcenv.cnfg lite/src lite/tool lite/sys/agent/seagent lite/sys/skeleton/svr_skeleton.h lite/sys/skeleton/svr_skeleton.a
    return $?
} #]]]#

_tuxedo()
{ #[[[#
    if [[ -z $TUXDIR || ! -x $TUXDIR/bin/buildclient ]]
    then
        echo "Error: Tuxedo not installed, skip svcenv.tuxedo"
        return 0
    fi

    cd tuxedo/sys       # /svcenv/tuxedo/sys
    cd agent            # /svcenv/tuxedo/src/agent
    make clean
    make release
    if (( $? != 0 ))
    then
        echo "Error: compile svcenv.tuxedo.sys.agent fail"
        return 1
    fi
    cd ..               # /svcenv/tuxedo/sys
    cd ../..            # /svcenv
    tar --exclude ".svn" -rf $pkg \
    tuxedo/etc/svcenv.sh tuxedo/etc/svcenv.cnfg tuxedo/src tuxedo/tool tuxedo/sys/agent/seagent tuxedo/sys/skeleton/svr_skeleton.h tuxedo/sys/skeleton/svr_skeleton.c
    return $?
} #]]]#

build_svcenv()
{ #[[[#
    local pkg=$RELEASE_DIR/svcenv.tar
    if [[ $CLEAN == N ]]
    then
        if [[ -f "${pkg}.gz" ]]
        then
            echo "svcenv already built"
            return 0
        fi
    fi
    rm -f ${pkg} ${pkg}.gz

    cd svcenv           # /svcenv

#----- lite -----#
    _lite
    if (( $? != 0 ))
    then
        return 1
    fi

#----- tuxedo -----#
    if [[ $OS == linux ]]
    then
        _tuxedo
        if (( $? != 0 ))
        then
            return 1
        fi
    fi

    cd ..               # /

    gzip $pkg

    echo "Build svcenv succeed"
} #]]]#

create_bin()
{ #[[[#
    local bin_block_size=1024
    local size=$(stat -c '%s' build/install_tmpl.sh)
    local bin_start=$((size / bin_block_size))
    if ((size%bin_block_size != 0))
    then ((++bin_start)); fi

    cd $RELEASE_DIR     # /build/_release

    local tgz
    local module
    local block
    for tgz in *.tar.gz
    do
        module=$(echo $tgz | cut -f1 -d".")
        eval local ${module}=$tgz
        eval local ${module}_start=$bin_start
        size=$(stat -c '%s' $tgz)
        ((block=size/bin_block_size))
        if ((size%bin_block_size != 0))
        then ((++block)); fi
        eval local ${module}_size=$size
        eval local ${module}_block=$block
        ((bin_start+=block))
    done

    local BIN=soar_${OS}_${CPU}_$(date +%Y%m%d).bin
    rm -f $BIN
    awk '
{
    gsub("%%BIN_BLOCK_SIZE%%", "'$bin_block_size'");
    gsub("%%COMMON%%", "'$common'");
    gsub("%%COMMON_START%%", "'$common_start'");
    gsub("%%COMMON_SIZE%%", "'$common_size'");
    gsub("%%WEB%%", "'$web'");
    gsub("%%WEB_START%%", "'$web_start'");
    gsub("%%WEB_SIZE%%", "'$web_size'");
    gsub("%%SVCNODE%%", "'$svcnode'");
    gsub("%%SVCNODE_START%%", "'$svcnode_start'");
    gsub("%%SVCNODE_SIZE%%", "'$svcnode_size'");
    gsub("%%SVCENV%%", "'$svcenv'");
    gsub("%%SVCENV_START%%", "'$svcenv_start'");
    gsub("%%SVCENV_SIZE%%", "'$svcenv_size'");
    print;
}
' ../install_tmpl.sh >$BIN

    for tgz in *.tar.gz
    do
        module=$(echo $tgz | cut -f1 -d".")
        dd if=$tgz of=$BIN bs=$bin_block_size count=$(eval echo \$${module}_block) seek=$(eval echo \$${module}_start) >/dev/null 2>&1
        if (($? != 0))
        then
            echo "Error: Attach package($tgz) fail"
            return 1
        fi
    done
    chmod a+x $BIN

    cd ../..            # /

    echo "Create BIN succeed"
} #]]]#

main()
{ #[[[#
    local option
    read -p "Clean build ? [N]: " option
    option=$(echo ${option:-D} | tr '[:lower:]' '[:upper:]')
    if [[ $option = Y || $option = YES ]]
    then CLEAN=Y; fi

    local ROOT_DIR=$(dirname $0)
    if [[ ${ROOT_DIR:0:1} != '/' ]]
    then
        ROOT_DIR=$PWD/$ROOT_DIR
    fi
    cd $ROOT_DIR
    RELEASE_DIR=$ROOT_DIR/build/_release
    mkdir $RELEASE_DIR
    echo
    echo "=================================================="
    echo

#--- common ---#
    build_common
    if (( $? != 0 ))
    then
        echo "Error: build common fail"
        return 1
    fi
    echo
    echo "=================================================="
    echo

#--- web ---#
    build_web
    if (( $? != 0 ))
    then
        echo "Error: build web fail"
        return 1
    fi
    echo
    echo "=================================================="
    echo

#--- svcnode ---#
    build_svcnode
    if (( $? != 0 ))
    then
        echo "Error: build svcnode fail"
        return 1
    fi
    echo
    echo "=================================================="
    echo

#--- svcenv ---#
    build_svcenv
    if (( $? != 0 ))
    then
        echo "Error: build svcenv fail"
        return 1
    fi
    echo
    echo "=================================================="
    echo

#--- generate install binary package ---#
    create_bin
    if (( $? != 0 ))
    then
        echo "Error: create install binary package fail"
        return 1
    fi
    echo
    echo "=================================================="
    echo

    echo "Building succeed"
    echo
    return 0
} #]]]#

OS=$(uname | tr '[:upper:]' '[:lower:]')
CPU=$(uname -m | tr '[:upper:]' '[:lower:]')
CLEAN=N
RELEASE_DIR=

main
exit $?
